//树数据相关操作
import { ID, OrderRule, TableRecord } from "/@/api/models";
//每一层数据的模型
export interface TreeDataItem<T> {
  children?: T[] | null;
  checkable?: boolean;
  transfterable?: boolean;
  [key: string]: any;
}

//TODO: 优化类型
// interface NodeItem<T extends TableRecord> {
//   checkable?: boolean;
//   transfterable?: boolean;
//   children?: NodeItem<T>[] | null;
//   [key in T]: any;
// }
// interface TargetItem {
//   id?: string;
//   name?: string;
//   icon?: string;
// }

/**
 * 递归遍历树数据或列表数据，找到key值为keyValue的item，并返回item所在一层的相关信息
 * @param data 树数据或列表数据
 * @param keyValue key的值
 * @param keyName key的字段名
 * @returns
 */
export function findItemByKey<T extends TreeDataItem<T>>(
  data: T[],
  keyValue: string | number,
  keyName = "id",
  parent?: T
): { item: T; index: number; items: T[]; parent?: T } | null {
  for (let i = 0, ii = data.length; i < ii; i++) {
    const item = data[i];
    if (item[keyName] === keyValue) {
      return {
        item,
        index: i,
        items: data,
        parent,
      };
    }
    if (item.children && item.children.length > 0) {
      const result = findItemByKey(item.children, keyValue, keyName, item);
      if (result) {
        return result;
      }
    }
  }
  return null;
}

/**
 * 递归遍历树数据，每个节点都执行一次loop回调
 * @param data 树数据
 * @param loop 执行回调，返回false终止遍历
 * @param parent 当前遍历的层的父节点
 * @param isReverse 遍历顺序，为false则反向遍历
 * @returns 返回false终止遍历
 */
export function loopItem<T extends TreeDataItem<T>>(
  data: T[],
  loop: (item: T, i: number, items: T[], parent?: T) => boolean | void,
  parent?: T,
  isReverse?: boolean
): boolean | void {
  const len = data.length;
  for (let i = isReverse ? len - 1 : 0; isReverse ? i >= 0 : i < len; isReverse ? i-- : i++) {
    const item = data[i];
    if (loop(item, i, data, parent) === false) {
      return false;
    }
    if (item.children && item.children.length > 0) {
      const result = loopItem(item.children, loop, item, isReverse);
      if (result === false) {
        return;
      }
    }
  }
}

/**
 * 递归树数据，找到目标节点的所有祖先节点
 * @param data 树数据
 * @param keyValue 目标节点id值
 * @param keyName 目标节点id键名
 * @param parentKeys 找到的所有祖先节点的id值数组
 * @param parentData 找到的所有祖先节点数据
 */
export function findParents<T extends TreeDataItem<T>>(
  data: T[],
  keyValue: ID,
  keyName = "id",
  parentKeys: ID[],
  parentData?: T[]
) {
  for (let i = 0, ii = data.length; i < ii; i++) {
    const item = data[i];
    if (item[keyName] === keyValue) {
      return false;
    }
    const ch = item.children;
    if (ch && ch.length > 0) {
      parentKeys.push(item[keyName]);
      parentData?.push(item);
      if (findParents(ch, keyValue, keyName, parentKeys, parentData) === false) {
        return false;
      }
    }
  }
  parentKeys.pop();
  parentData?.pop();
}

export function sortItems<T extends TreeDataItem<T>>(data: T[], sortKey = "sortValue", sortOrder = OrderRule.ASC) {
  data.sort((a, b) => {
    const v1 = a[sortKey] || 0;
    const v2 = b[sortKey] || 0;
    return sortOrder === OrderRule.ASC ? v1 - v2 : v2 - v1;
  });
  for (let i = 0, ii = data.length; i < ii; i++) {
    const item = data[i];
    const ch = item.children;
    if (ch && ch.length > 0) {
      sortItems(ch, sortKey, sortOrder);
    }
  }
}
